package com.itheima.spring.bestpractive.service.impl;

import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.itheima.spring.bestpractive.common.exception.BizEnum;
import com.itheima.spring.bestpractive.common.exception.BizException;
import com.itheima.spring.bestpractive.common.util.JwtUtil;
import com.itheima.spring.bestpractive.mapping.EmpMapping;
import com.itheima.spring.bestpractive.pojo.Employee;
import com.itheima.spring.bestpractive.service.EmpService;
import com.itheima.spring.bestpractive.utils.MinioUtil;
import com.itheima.spring.bestpractive.vo.req.employee.EmpLogin2ReqVo;
import com.itheima.spring.bestpractive.vo.req.employee.EmpReqAdminVo;
import com.itheima.spring.bestpractive.vo.req.employee.EmpReqVo;
import com.itheima.spring.bestpractive.vo.req.employee.EmpUpdataVo;
import com.itheima.spring.bestpractive.vo.resp.employee.EmpRespVo;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;

import java.util.List;
import java.util.Map;
import java.util.concurrent.TimeUnit;

/**
 * @version 1.0
 * @author: HZY
 * @date: 2025/6/25 14:19
 * @Content:
 */
@Service
@Transactional
public class EmpServiceImpl implements EmpService {
    @Autowired
    EmpMapping empMapping;
    @Autowired
    JwtUtil jwtUtil;
    @Autowired
    private ObjectMapper objectMapper;
    @Autowired
    private RedisTemplate<String, String> redisTemplate;
    @Autowired
    private MinioUtil minioUtil;

    @Override
    public EmpRespVo getEmp(EmpReqVo empReqVo) throws JsonProcessingException {
        EmpRespVo empRespVo = empMapping.getEmp(empReqVo);
        if (empRespVo == null) {
            throw new BizException(BizEnum.USER_NOT_EXIST);
        }
        String file = minioUtil.getFile(empRespVo.getPhoto());
        empRespVo.setPhoto(file);

        empMapping.updateLastLoginTime(empReqVo.getEmployeeId());
        empMapping.updateLoginTime(empReqVo.getEmployeeId());
        String newToken = jwtUtil.generateToken(String.valueOf(empRespVo.getEmployeeId()), empRespVo.getName(),empRespVo.getUserRole().getRoleId());
        String emp = objectMapper.writeValueAsString(empRespVo);

        //更新缓存
        String redisKeyToken = "token:" + empReqVo.getEmployeeId();
        String redisKeyEmp = "emp:" + empReqVo.getEmployeeId();


        if(redisTemplate.opsForValue().get(redisKeyToken) != null){
            redisTemplate.delete(redisKeyToken);
        }
        if(redisTemplate.opsForValue().get(redisKeyEmp) != null){
            redisTemplate.delete(redisKeyEmp);
        }
        redisTemplate.opsForValue().set(redisKeyToken,newToken,1, TimeUnit.DAYS);
        redisTemplate.opsForValue().set(redisKeyEmp,emp,1, TimeUnit.DAYS);
        empRespVo.setToken(newToken);
        return empRespVo;
    }

    @Override
    public void logout(long employeeId) {
        redisTemplate.delete("token:" + employeeId);
        redisTemplate.delete("emp:" + employeeId);
    }

    @Transactional
    @Override
    public void empAdd(EmpReqAdminVo employee, MultipartFile file) {
        String s = minioUtil.uploadFile(file);
        Employee employee1 = new Employee();
        BeanUtils.copyProperties(employee, employee1);
        employee1.setPhoto(s);
        empMapping.insertEmp(employee1);
        empMapping.insertEmpRoleRelation(employee1.getEmployeeId());
    }

    @Override
    public EmpRespVo getEmpFromCache(long empId) throws JsonProcessingException {
        String s = redisTemplate.opsForValue().get("emp:" + empId);
        EmpRespVo empRespVo = objectMapper.readValue(s, EmpRespVo.class);
        String phone = empRespVo.getPhone();
        empRespVo.setPhone(phone.substring(0,3) + "****" + phone.substring(7));
        String idCard = empRespVo.getIdCard();
        empRespVo.setIdCard(idCard.substring(0,4) + "**********" + idCard.substring(14));
        return empRespVo;
    }

    @Override
    public List<EmpRespVo> getAllEvaluator() {

        return empMapping.getAllEvaluator();
    }

    @Override
    public List<EmpRespVo> getAllEmp(int pageNum, int pageSize) {
        List<EmpRespVo> allEmp = empMapping.getAllEmp(pageNum, pageSize);
        allEmp.forEach(empRespVo -> {
            String file = minioUtil.getFile(empRespVo.getPhoto());
            empRespVo.setPhoto(file);
        });
        return empMapping.getAllEmp(pageNum, pageSize);
    }

    @Override
    public long getEmpByPhoneAndId(EmpLogin2ReqVo empLogin2ReqVo) {
        Long empByPhoneAndId = empMapping.getEmpByPhoneAndId(empLogin2ReqVo);
        if(empByPhoneAndId == null){
            throw new BizException(BizEnum.DATA_NOT_FOUND);
        }
        return empByPhoneAndId;
    }

    @Override
    public void updateEmpPassword(Employee employee) {
        empMapping.updateEmpPassword(employee);
    }

    @Override
    public void updateEmp(EmpUpdataVo empVo, MultipartFile photo) {
        String s = null;
        Employee employee = new Employee();
        BeanUtils.copyProperties(empVo,employee);
        if(photo != null && !photo.isEmpty()){
            s = minioUtil.uploadFile(photo);
            employee.setPhoto(s);
        }
        empMapping.updateEmp(employee);
        empMapping.updateEmp2(empVo);
    }

    @Override
    public void updatePlanStatus(Map<String, Object> data) {
         long employeeId = Long.parseLong((String) data.get("employeeId"));
         long planId = Long.parseLong((String) data.get("planId"));
         int status = Integer.parseInt((String) data.get("status"));
         empMapping.updatePlanStatus(planId,employeeId,status);

    }
}
